package org.jsola.hr.service.impl;

import cn.hutool.core.collection.ListUtil;
import org.jsola.admin.vo.SiteVO;
import org.jsola.core.Page;
import org.jsola.exception.ParamException;
import org.jsola.hr.common.ExampleKit;
import org.jsola.hr.common.PageListUtil;
import org.jsola.hr.constant.ChannelGroupJurisdiction;
import org.jsola.hr.constant.HrConstants;
import org.jsola.hr.constant.HrPermissionConstants;
import org.jsola.hr.dao.IChannelGroupDAO;
import org.jsola.hr.dto.ChannelGroupAddDTO;
import org.jsola.hr.dto.ChannelGroupUpdateDTO;
import org.jsola.hr.entity.ChannelDO;
import org.jsola.hr.entity.ChannelGroupDO;
import org.jsola.hr.entity.ChannelGroupJurisdictionDO;
import org.jsola.hr.entity.ChannelGroupUserDO;
import org.jsola.hr.provider.IPermissionProviderService;
import org.jsola.hr.provider.ISalaryProviderService;
import org.jsola.hr.provider.ISiteProviderService;
import org.jsola.hr.provider.IUserProviderService;
import org.jsola.hr.query.*;
import org.jsola.hr.service.IChannelGroupJurisdictionService;
import org.jsola.hr.service.IChannelGroupService;
import org.jsola.hr.service.IChannelGroupUserService;
import org.jsola.hr.service.IChannelService;
import org.jsola.hr.vo.*;
import org.jsola.permission.constant.PermissionConstants;
import org.jsola.salary.query.ChannelFeeSettlementQuery;
import org.jsola.salary.vo.ChannelFeeSettlementVO;
import org.jsola.salary.vo.excel.ChannelFeeSettlementExportVO;
import org.jsola.user.core.TokenUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import tk.mybatis.mapper.entity.Example;

import java.util.*;
import java.util.stream.Collectors;

import static org.jsola.hr.constant.HrPermissionConstants.HR_DEFAULT_SUBJECT_ID;
import static org.jsola.hr.constant.HrPermissionConstants.SYSTEM_SUBJECT_TYPE;

/**
 * 渠道分组表
 *
 * @author zhr
 */
@Service("hrChannelGroupServiceImpl")
public class ChannelGroupServiceImpl implements IChannelGroupService {

    @Autowired
    private IChannelGroupDAO channelGroupDAO;

    @Autowired
    private IPermissionProviderService permissionProviderService;

    @Autowired
    private IChannelGroupJurisdictionService channelGroupJurisdictionService;

    @Autowired
    private IChannelGroupUserService channelGroupUserService;

    @Autowired
    private IUserProviderService userProviderService;

    @Autowired
    private IChannelService channelService;

    @Autowired
    private ISiteProviderService siteProviderService;

    @Autowired
    private ISalaryProviderService salaryProviderService;

    @Override
    public List<ChannelFeeSettlementExportVO> channelFeeSettlementExport(ChannelFeeSettlementQuery channelFeeSettlementQuery, TokenUser tokenUser) {
        if (channelFeeSettlementQuery.getLevel() == 1) {
            List<String> channelGroupIdList = new ArrayList<>();
            int myJurisdiction = channelGroupJurisdictionService.getMyJurisdiction(tokenUser);
            if (myJurisdiction != 0 && myJurisdiction != 2) {
                if (myJurisdiction == 1) {
                    channelGroupIdList.add(HrConstants.DEFAULT.toUpperCase());
                }
                //查询所有管理的组id
                List<ChannelGroupUserDO> channelGroupUserDOList = channelGroupUserService.selectGroupByUserId(tokenUser.getUserId(), tokenUser);
                channelGroupUserDOList.forEach(p -> channelGroupIdList.add(p.getChannelGroupId()));
                channelFeeSettlementQuery.setChannelGroupIdList(channelGroupIdList);
            }
        }
        List<ChannelFeeSettlementExportVO> channelFeeSettlementExportVOList = salaryProviderService.selectExportList(channelFeeSettlementQuery, tokenUser);
        channelFeeSettlementExportVOList.forEach(p -> p.setChannelGroupName(StringUtils.isEmpty(p.getChannelGroupName()) ? "默认分组" : p.getChannelGroupName()));
        return channelFeeSettlementExportVOList;
    }

    @Override
    public Page<ChannelFeeSettlementVO> getChannelFeeSettlement(ChannelFeeSettlementQuery channelFeeSettlementQuery, TokenUser tokenUser) {
        if (channelFeeSettlementQuery.getLevel() == 1) {
            List<String> channelGroupIdList = new ArrayList<>();
            int myJurisdiction = channelGroupJurisdictionService.getMyJurisdiction(tokenUser);
            if (myJurisdiction != 0 && myJurisdiction != 2) {
                if (myJurisdiction == 1) {
                    channelGroupIdList.add(HrConstants.DEFAULT.toUpperCase());
                }
                //查询所有管理的组id
                List<ChannelGroupUserDO> channelGroupUserDOList = channelGroupUserService.selectGroupByUserId(tokenUser.getUserId(), tokenUser);
                channelGroupUserDOList.forEach(p -> channelGroupIdList.add(p.getChannelGroupId()));
                channelFeeSettlementQuery.setChannelGroupIdList(channelGroupIdList);
            }
        }
        List<ChannelFeeSettlementVO> channelFeeSettlement = salaryProviderService.getChannelFeeSettlement(channelFeeSettlementQuery, tokenUser);
        if (!CollectionUtils.isEmpty(channelFeeSettlement)) {
            List<ChannelFeeSettlementVO> list = PageListUtil.startPage(channelFeeSettlement, channelFeeSettlementQuery.getPageNo(), channelFeeSettlementQuery.getPageSize());
            list.forEach(p -> p.setChannelGroupName(StringUtils.isEmpty(p.getChannelGroupName()) ? "默认分组" : p.getChannelGroupName()));
            return new Page<>(list, channelFeeSettlementQuery.getPageNo(), channelFeeSettlementQuery.getPageSize(), channelFeeSettlement.size());
        }
        return null;
    }

    @Override
    public Page<HrUserVO> getNotDistributionUser(ChannelGroupQuery channelGroupQuery, TokenUser tokenUser) {
        List<String> userList;
        List<HrUserVO> hrUserVOS = userProviderService.queryUserList(new HrUserQuery(), tokenUser);
        Map<String, HrUserVO> userVOMap = hrUserVOS.stream().collect(Collectors.toMap(HrUserVO::getId, p -> p));
        //分组级别
        ChannelGroupVO channelGroupVO = selectById(channelGroupQuery.getGroupId(), tokenUser.getSiteId());
        ParamException.isFalse((channelGroupVO == null || channelGroupVO.getId() == null) && !HrConstants.DEFAULT.toUpperCase().equals(channelGroupQuery.getGroupId()), "渠道分组未找到");
        if (HrConstants.DEFAULT.toUpperCase().equals(channelGroupQuery.getGroupId()) || channelGroupVO.getLevel() == 1) {
            int jurisdiction = HrConstants.DEFAULT.toUpperCase().equals(channelGroupQuery.getGroupId()) ? ChannelGroupJurisdiction.GROUP_DEFAULT.getValue() : ChannelGroupJurisdiction.GROUP_ALL.getValue();
            List<ChannelGroupJurisdictionDO> allManagerByJurisdiction = channelGroupJurisdictionService.getAllManagerByJurisdiction(jurisdiction, tokenUser);
            userList = allManagerByJurisdiction.stream().map(ChannelGroupJurisdictionDO::getUserId).collect(Collectors.toList());
        } else {
            //查询分组的所有用户
            userList = channelGroupUserService.getAllManagerByGroupId(channelGroupQuery.getGroupId(), tokenUser).stream().map(p -> p.getUserId()).collect(Collectors.toList());
        }
        for (String userId : userList) {
            userVOMap.remove(userId);
        }
        List<HrUserVO> hrUserVOS1 = new ArrayList<>();
        for (Map.Entry<String, HrUserVO> stringHrUserVOEntry : userVOMap.entrySet()) {
            hrUserVOS1.add(stringHrUserVOEntry.getValue());
        }
        //名字过滤
        if (!StringUtils.isEmpty(channelGroupQuery.getNameOrPhone())) {
            hrUserVOS1.removeIf(next -> !next.getName().contains(channelGroupQuery.getNameOrPhone()) && !next.getPhone().contains(channelGroupQuery.getNameOrPhone()));
        }
        //分页
        List<HrUserVO> list = PageListUtil.startPage(hrUserVOS1, channelGroupQuery.getPageNo(), channelGroupQuery.getPageSize());
        return new Page<HrUserVO>(list, channelGroupQuery.getPageNo(), channelGroupQuery.getPageSize(), hrUserVOS1.size());
    }

    @Override
    public ChannelGroupVO selectByChannelName(String channelName, TokenUser tokenUser) {
        Example example = new Example(ChannelGroupDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("siteId", tokenUser.getSiteId())
                .andEqualTo("name", channelName);
        ChannelGroupDO channelGroupDO = channelGroupDAO.selectOneByExample(example);
        if (channelGroupDO == null || channelGroupDO.getId() == null) {
            return null;
        }
        return channelGroupDAO.selectOneByExample(example).to(ChannelGroupVO.class);
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public ChannelGroupsVO getMyChannelGroup(ChannelGroupQuery channelGroupQuery, TokenUser tokenUser) {
        int number = 0;
        List<ChannelGroupListVO> channelGroupListVOS = new ArrayList<>();
        List<ChannelGroupListVO> returnChannelGroupListVOList = new ArrayList<>();
        ChannelGroupsVO channelGroupsVO = new ChannelGroupsVO();
        ChannelGroupDO channelGroupDO = null;
        //查询是否有一级分组
        List<ChannelGroupDO> groupByLevel = getGroupByLevel(1, tokenUser);
        if (!CollectionUtils.isEmpty(groupByLevel)) {
            channelGroupDO = groupByLevel.get(0);
        } else {
            ChannelGroupAddDTO channelGroupAddDTO = new ChannelGroupAddDTO();
            SiteVO siteVO = siteProviderService.selectById(tokenUser.getSiteId(), tokenUser.getSiteId());
            channelGroupAddDTO.setName(siteVO.getName());
            channelGroupAddDTO.setLevel(1);
            channelGroupDO = save(channelGroupAddDTO, tokenUser).to(ChannelGroupDO.class);
        }
        channelGroupsVO.setName(channelGroupDO.getName());
        channelGroupsVO.setId(channelGroupDO.getId());
        if (!StringUtils.isEmpty(channelGroupDO.getDescribe())) {
            channelGroupsVO.setDescribe(channelGroupDO.getDescribe());
        }

        //查询自己的所有分组
        //是否超级管理员
        String userId = permissionProviderService.findMemberIdBySubject(PermissionConstants.ROLE_MEMBER_TYPE_USER,
                SYSTEM_SUBJECT_TYPE, HR_DEFAULT_SUBJECT_ID, tokenUser.getSiteId());
        if (tokenUser.getUserId().equals(userId)) {
            channelGroupsVO.setJurisdiction(1);
            List<ChannelGroupListVO> channelGroupListVOS1;
            List<ChannelGroupDO> groupByLevel1 = getGroupByLevel(2, tokenUser);
            if (CollectionUtils.isEmpty(groupByLevel1)) {
                channelGroupListVOS1 = new ArrayList<>();
            } else {
                channelGroupListVOS1 = groupByLevel1.stream()
                        .map(channelGroupDO1 -> channelGroupDO1.to(ChannelGroupListVO.class))
                        .collect(Collectors.toList());
            }
            ChannelGroupListVO channelGroupListVO = new ChannelGroupListVO();
            channelGroupListVO.setId("DEFAULT");
            channelGroupListVO.setName("默认分组");
            channelGroupListVO.setDescribe("默认分组是系统提供的分组，不可删除不可修改分组名称。");
            channelGroupListVOS.add(channelGroupListVO);
            channelGroupListVOS.addAll(channelGroupListVOS1);
        } else {
            //是否有分组权限
            ChannelGroupJurisdictionQuery channelGroupJurisdictionQuery = new ChannelGroupJurisdictionQuery();
            channelGroupJurisdictionQuery.setUserId(tokenUser.getUserId());
            List<ChannelGroupJurisdictionListVO> select = channelGroupJurisdictionService.select(channelGroupJurisdictionQuery, tokenUser.getSiteId());
            if (!CollectionUtils.isEmpty(select) && ChannelGroupJurisdiction.GROUP_ALL.getValue().equals(select.get(0).getJurisdiction())) {
                channelGroupsVO.setJurisdiction(2);
                List<ChannelGroupDO> channelGroupDOS = getGroupByLevel(2, tokenUser);
                ChannelGroupListVO channelGroupListVO = new ChannelGroupListVO();
                channelGroupListVO.setId("DEFAULT");
                channelGroupListVO.setName("默认分组");
                channelGroupListVO.setDescribe("默认分组是系统提供的分组，不可删除不可修改分组名称。");
                channelGroupListVOS.add(channelGroupListVO);
                if(!CollectionUtils.isEmpty(channelGroupDOS)) {
                    for (ChannelGroupDO groupDO : channelGroupDOS) {
                        channelGroupListVOS.add(groupDO.to(ChannelGroupListVO.class));
                    }
                }
            } else {
                channelGroupsVO.setJurisdiction(3);
                if (!CollectionUtils.isEmpty(select) && ChannelGroupJurisdiction.GROUP_DEFAULT.getValue().equals(select.get(0).getJurisdiction())) {
                    ChannelGroupListVO channelGroupListVO = new ChannelGroupListVO();
                    channelGroupListVO.setId("DEFAULT");
                    channelGroupListVO.setName("默认分组");
                    channelGroupListVO.setDescribe("默认分组是系统提供的分组，不可删除不可修改分组名称。");
                    channelGroupListVOS.add(channelGroupListVO);
                }
                //没有权限去分组用户中间表查分组主管权限
                ChannelGroupUserQuery channelGroupUserQuery = new ChannelGroupUserQuery();
                channelGroupUserQuery.setUserId(tokenUser.getUserId());
                List<ChannelGroupUserListVO> select1 = channelGroupUserService.select(channelGroupUserQuery, tokenUser.getSiteId());
                List<String> channelGroupIdList = new ArrayList<>();
                select1.forEach(channelGroupUserListVO -> channelGroupIdList.add(channelGroupUserListVO.getChannelGroupId()));
                if (!CollectionUtils.isEmpty(channelGroupIdList)) {
                    ChannelGroupQuery channelGroupQuery1 = new ChannelGroupQuery();
                    channelGroupQuery1.setChannelGroupIdList(channelGroupIdList);
                    List<ChannelGroupListVO> channelGroupListVOS1 = select(channelGroupQuery1, tokenUser.getSiteId());
                    channelGroupListVOS.addAll(channelGroupListVOS1);
                }
            }
        }
        //管理员筛选组
        if (!StringUtils.isEmpty(channelGroupQuery.getGroupNameOrUserName())) {
            List<ChannelGroupListVO> channelGroupListVOS1 = new ArrayList<>(channelGroupListVOS);
            //查询分组的管理员
            Iterator<ChannelGroupListVO> iterator = channelGroupListVOS1.iterator();
            while (iterator.hasNext()) {
                ChannelGroupListVO channelGroupListVO = iterator.next();
                //查询默认分组的管理员
                ChannelGroupUserQuery channelGroupUserQuery = new ChannelGroupUserQuery();
                if (HrConstants.DEFAULT.toUpperCase().equals(channelGroupListVO.getId())) {
                    channelGroupUserQuery.setJurisdiction(ChannelGroupJurisdiction.GROUP_DEFAULT.getValue());
                } else {
                    channelGroupUserQuery.setJurisdiction(-1);
                }
                channelGroupUserQuery.setGroupId(channelGroupListVO.getId());
                List<ChannelGroupUserListVO> userByGroupId = channelGroupUserService.getUserByGroupId(channelGroupUserQuery, tokenUser);
                if (CollectionUtils.isEmpty(userByGroupId)) {
                    iterator.remove();
                    continue;
                }
                for (int i = 0; i < userByGroupId.size(); i++) {
                    ChannelGroupUserListVO channelGroupUserListVO = userByGroupId.get(i);
                    if (channelGroupUserListVO.getUserName().contains(channelGroupQuery.getGroupNameOrUserName())) {
                        break;
                    }
                    if (i == userByGroupId.size() - 1) {
                        iterator.remove();
                    }
                }
            }
            //组名筛选
            List<ChannelGroupListVO> channelGroupListVOS2 = new ArrayList<>(channelGroupListVOS);
            channelGroupListVOS2.removeIf(groupListVO -> !groupListVO.getName().contains(channelGroupQuery.getGroupNameOrUserName()));

            //并集
            channelGroupListVOS2.removeAll(channelGroupListVOS1);
            channelGroupListVOS2.addAll(channelGroupListVOS1);
            if (channelGroupListVOS.size() != channelGroupListVOS2.size()) {
                channelGroupsVO.setId(null);
            }
            channelGroupListVOS.clear();
            channelGroupListVOS.addAll(channelGroupListVOS2);
        }
        //查询分组的渠道数量
        for (ChannelGroupListVO channelGroupListVO : channelGroupListVOS) {
            ChannelQuery channelQuery = new ChannelQuery();
            channelQuery.setLevel(2);
            channelQuery.setChannelGroupId(channelGroupListVO.getId());
            Integer integer = channelService.pageChannelList(channelQuery, tokenUser).getEntityCount();
            number += integer;
            channelGroupListVO.setNumber(integer);
        }
        channelGroupsVO.setChannelGroupVOList(channelGroupListVOS);
        channelGroupsVO.setNumber(number);
        if (channelGroupsVO.getJurisdiction() == 3) {
            channelGroupsVO.setId(null);
        }
        return channelGroupsVO;
    }

    /**
     * 按级别获取租户的分组
     *
     * @param level     分组级别
     * @param tokenUser 当前用户
     * @return 分组
     */
    private List<ChannelGroupDO> getGroupByLevel(Integer level, TokenUser tokenUser) {
        Example example = new Example(ChannelGroupDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("siteId", tokenUser.getSiteId())
                .andEqualTo("level", level);
        List<ChannelGroupDO> channelGroupDOS = channelGroupDAO.selectByExample(example);
        if (CollectionUtils.isEmpty(channelGroupDOS)) {
            return new ArrayList<>();
        } else {
            return channelGroupDOS;
        }
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public ChannelGroupVO save(ChannelGroupAddDTO channelGroupAddDTO, TokenUser tokenUser) {
        ParamException.isFalse("默认分组".equals(channelGroupAddDTO.getName()), "该分组名已被创建");
        // 转DO
        ChannelGroupDO channelGroupDO = channelGroupAddDTO.to(ChannelGroupDO.class);
        //校验分组名
        ChannelGroupVO channelGroupVO1 = selectByChannelName(channelGroupAddDTO.getName(), tokenUser);
        if (channelGroupVO1 != null) {
            throw new ParamException("该分组名已被创建");
        }
        // 保存
        channelGroupDO = save(channelGroupDO, tokenUser.getSiteId(), tokenUser.getUserId());
        ChannelGroupVO channelGroupVO = channelGroupDO.to(ChannelGroupVO.class);
        return channelGroupVO;
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public int update(ChannelGroupUpdateDTO channelGroupUpdateDTO, TokenUser tokenUser) {
        //校验重复名
        Example example = new Example(ChannelGroupDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("siteId", tokenUser.getSiteId())
                .andEqualTo("name", channelGroupUpdateDTO.getName())
                .andNotEqualTo("id", channelGroupUpdateDTO.getId());
        List<ChannelGroupDO> channelGroupDOS = channelGroupDAO.selectByExample(example);
        ParamException.isTrue(CollectionUtils.isEmpty(channelGroupDOS), "分组名已被创建");
        //转DO
        ChannelGroupDO channelGroupDO = channelGroupUpdateDTO.to(ChannelGroupDO.class);
        //根据主键更新，只更新非null值
        return updateByIdSelective(channelGroupDO, tokenUser.getSiteId(), tokenUser.getUserId());
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public int deleteByIds(TokenUser tokenUser, String... channelGroupIds) {
        //校验分组中是否有渠道
        for (String channelGroupId : channelGroupIds) {
            List<ChannelDO> channelDOS = channelService.selectByGroupId(channelGroupId, tokenUser);
            ParamException.isTrue(CollectionUtils.isEmpty(channelDOS), "该分组下有员工，不可删除");
        }
        return logicalDeleteByIds(tokenUser.getSiteId(), tokenUser.getUserId(), (Object[]) channelGroupIds);
    }


    @Override
    public ChannelGroupVO selectById(String channelGroupId, String siteId) {
        ChannelGroupDO channelGroupDO = selectDOById(channelGroupId, siteId);
        if (channelGroupDO == null) {
            return null;
        }
        return channelGroupDO.to(ChannelGroupVO.class);
    }

    @Override
    public List<ChannelGroupListVO> select(ChannelGroupQuery channelGroupQuery, String siteId) {
        List<ChannelGroupDO> channelGroupDOList = selectDO(channelGroupQuery, siteId);
        if (CollectionUtils.isEmpty(channelGroupDOList)) {
            return channelGroupDOList == null ? null : new ArrayList<>();
        }
        return channelGroupDOList.stream()
                .map(channelGroupDO -> channelGroupDO.to(ChannelGroupListVO.class))
                .collect(Collectors.toList());
    }

    @Override
    public int selectCount(ChannelGroupQuery channelGroupQuery, String siteId) {
        Example example = buildExample(channelGroupQuery, siteId);
        return channelGroupDAO.selectCountByExample(example);
    }

    @Override
    public Page<ChannelGroupListVO> selectPage(ChannelGroupQuery channelGroupQuery, String siteId) {
        Example example = buildExample(channelGroupQuery, siteId);
        Page<ChannelGroupDO> page = channelGroupDAO.selectPageByExample(example,
                channelGroupQuery.getPageNo(),
                channelGroupQuery.getPageSize());

        return page.to(ChannelGroupListVO.class);
    }

    @Override
    public ChannelGroupDO selectDOById(String channelGroupId, String siteId) {
        return listById(channelGroupId, siteId);
    }

    @Override
    public List<ChannelGroupDO> selectDO(ChannelGroupQuery channelGroupQuery, String siteId) {
        Example example = buildExample(channelGroupQuery, siteId);
        return channelGroupDAO.selectByExample(example);
    }


    /**
     * 根据查询参数，构建example
     *
     * @param channelGroupQuery 查询参数
     * @param siteId            所属站点id
     * @return example
     */
    private Example buildExample(ChannelGroupQuery channelGroupQuery, String siteId) {
        Example example = new Example(ChannelGroupDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("siteId", siteId);
        if (!CollectionUtils.isEmpty(channelGroupQuery.getChannelGroupIdList())) {
            example.and().andIn("id", channelGroupQuery.getChannelGroupIdList());
        }
        if (channelGroupQuery.getLevel() != null) {
            example.and().andEqualTo("level", channelGroupQuery.getLevel());
        }
        // 排序
        ExampleKit.setExampleOrder(example, channelGroupQuery.getOrders());
        return example;
    }
}




